package com.wlyuan.open.domain.source.service.impl;

import com.alibaba.fastjson.JSON;
import com.wlyuan.basic.api.*;
import com.wlyuan.basic.dto.customer.CustomerDetailDTO;
import com.wlyuan.cert.api.ICertService;
import com.wlyuan.core.exception.AssertUtils;
import com.wlyuan.open.domain.source.assembler.*;
import com.wlyuan.open.domain.source.service.IOpenBasicService;
import com.wlyuan.open.dto.*;
import com.wlyuan.open.infrastructure.exception.SourceValueErrorException;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

/**
 * @author yuanzheng
 */
@RequiredArgsConstructor
@Slf4j
@Service
@Data
public class OpenBasicServiceImpl implements IOpenBasicService {
    @DubboReference(check = false, timeout = 100000)
    private ICustomerService customerService;
    @DubboReference(check = false)
    private IConsigneeService consigneeService;
    @DubboReference(check = false)
    private IGoodsService goodsService;
    @DubboReference(check = false)
    private ICarrierService carrierService;
    @DubboReference(check = false)
    private IDriverService driverService;
    @DubboReference(check = false)
    private IVehicleService vehicleService;
    @DubboReference(check = false)
    private final ICertService certService;
    @DubboReference(check = false)
    private final IRelationService relationService;

    private CustomerDetailDTO getCustomerByName(String customerName, Long tenantId) {
        if (StringUtils.isBlank(customerName)) {
            throw new SourceValueErrorException("客户名称不能为空");
        }
        var customer = customerService.getCustomerByName(customerName, tenantId);
        if (null == customer) {
            logger.error("客户名称不存在: {} {}", customerName, tenantId);
            throw new SourceValueErrorException("客户名称不存在" + ":" + customerName + ":" + tenantId);
        }
        return customer;
    }

    @Override
    public Long sync(OpenCustomerSyncDTO source) {
        // source.getCustomerId() 为新系统中的客户ID，也是t_source_relation中的target_id，为空，则为数据未同步
        var creation = CustomerAssembler.assemble(source);
        logger.info("创建客户请求：{}", JSON.toJSON(creation));
        var customer = customerService.rewriteSource(creation);
        AssertUtils.assertNotNull(customer, new SourceValueErrorException("创建客户失败"), source);
        return customer.getCustomerId();
    }

    @Override
    public Long sync(OpenConsigneeSyncDTO source) {
        // source.getConsigneeId() 为新系统中的ID，也是t_source_relation中的target_id
        CustomerDetailDTO customer = this.getCustomerByName(source.getCustomerName(), source.getTenantId());
        var creation = ConsigneeAssembler.assemble(source, customer.getCustomerId());
        logger.info("创建收货方请求:{}", JSON.toJSON(creation));
        var consignee = consigneeService.rewrite(creation);
        AssertUtils.assertNotNull(consignee, new SourceValueErrorException("创建收货方失败"), source);
        return consignee.getConsigneeId();
    }

    @Override
    public Long sync(OpenGoodsSyncDTO source) {
        //source.getGoodsId() 为新系统中的物品ID，也是t_source_relation中的target_id
        var customer = this.getCustomerByName(source.getCustomerName(), source.getTenantId());
        if (StringUtils.isBlank(source.getType())) {
            throw new SourceValueErrorException("物品类型不能为空");
        }
        var creation = GoodsAssembler.assemble(source, customer.getCustomerId());
        logger.info("创建物品请求:{}", JSON.toJSON(creation));
        var goods = goodsService.rewriteSource(creation);
        AssertUtils.assertNotNull(goods, new SourceValueErrorException("创建物品失败"), source);
        return goods.getGoodsId();
    }

    @Override
    public Long sync(OpenCarrierSyncDTO source) {
        //source.getCarrierId() 为新系统中的承运方ID，也是t_source_relation中的target_id
        var creation = CarrierAssembler.assemble(source);
        logger.info("创建承运方请求:{}", JSON.toJSON(creation));
        var carrier = carrierService.rewrite(creation);
        AssertUtils.assertNotNull(carrier, new SourceValueErrorException("创建承运方失败"), source);
        return carrier.getCarrierId();
    }

    @Override
    public Long sync(OpenDriverSyncDTO source) {
        //source.getDriverId() 为新系统中的司机ID，也是t_source_relation中的target_id
        var creation = DriverAssembler.assemble(source);
        logger.info("创建司机请求:{}", JSON.toJSON(creation));
        var driver = driverService.rewrite(creation);
        AssertUtils.assertNotNull(driver, new SourceValueErrorException("创建司机失败"), source);
        return driver.getDriverId();
    }

    @Override
    public Long sync(OpenVehicleSyncDTO source) {
        //source.getVehicleId() 为新系统中的车辆ID，也是t_source_relation中的target_id
        var creation = VehicleAssembler.assemble(source);
        logger.info("创建车辆请求:{}", JSON.toJSON(creation));
        var vehicle = vehicleService.rewrite(creation);
        AssertUtils.assertNotNull(vehicle, new SourceValueErrorException("创建车辆失败"), source);
        return vehicle.getVehicleId();
    }

    @Override
    public Long sync(OpenContractSyncDTO source) {
        var creation = ContractAssembler.assemble(source);
        logger.info("创建合同请求:{}", JSON.toJSON(creation));
        var contract = certService.contractRewrite(creation);
        AssertUtils.assertNotNull(contract, new SourceValueErrorException("创建合同失败"), source);
        return Long.valueOf(contract);
    }

    @Override
    public Long sync(OpenRelationSyncDTO source) {
        var creation = RelationAssembler.assembler(source);
        logger.info("创建承运方邀请关系请求:{}", JSON.toJSON(creation));
        var relation = relationService.rewrite(creation);
        AssertUtils.assertNotNull(relation, new SourceValueErrorException("创建承运方邀请关系失败"), source);
        return relation.getRelationId();
    }

}
